#!/usr/bin/python3
# coding: utf-8
import os
import ahocorasick
from onecup.settings import BASE_DIR


class QuestionClassifier:
    def __init__(self):
        # 　特征词路径
        self.error_path = os.path.join(BASE_DIR, 'chatbot/dict/error.txt')
        self.link_module_path = os.path.join(BASE_DIR, 'chatbot/dict/link_module.txt')
        self.check_way_path = os.path.join(BASE_DIR, 'chatbot/dict/check_way.txt')
        self.solve_way_path = os.path.join(BASE_DIR, 'chatbot/dict/solve_way.txt')
        self.server_path = os.path.join(BASE_DIR, 'chatbot/dict/server.txt')
        self.err_effect_path = os.path.join(BASE_DIR, 'chatbot/dict/err_effect.txt')
        self.err_cause_path = os.path.join(BASE_DIR, 'chatbot/dict/err_cause.txt')
        # 加载特征词
        self.error_wds = [i.strip() for i in open(self.error_path, 'r', encoding='utf-8') if i.strip()]
        self.link_module_wds = [i.strip() for i in open(self.link_module_path, 'r', encoding='utf-8') if i.strip()]
        self.check_way_wds = [i.strip() for i in open(self.check_way_path, 'r', encoding='utf-8') if i.strip()]
        self.solve_way_wds = [i.strip() for i in open(self.solve_way_path, 'r', encoding='utf-8') if i.strip()]
        self.server_wds = [i.strip() for i in open(self.server_path, 'r', encoding='utf-8') if i.strip()]
        self.err_effect_wds = [i.strip() for i in open(self.err_effect_path, 'r', encoding='utf-8') if i.strip()]
        self.err_cause_wds = [i.strip() for i in open(self.err_cause_path, 'r', encoding='utf-8') if i.strip()]
        self.region_words = set(
            self.link_module_wds + self.error_wds + self.check_way_wds + self.solve_way_wds + self.server_wds + self.err_effect_wds + self.err_cause_wds)
        # 构造领域actree
        self.region_tree = self.build_actree(list(self.region_words))
        # 构建词典
        self.wdtype_dict = self.build_wdtype_dict()
        # 问句疑问词
        self.err_cause_qwds = ['原因', '成因', '为什么', '怎么会', '怎样才', '咋样才', '怎样会', '如何会', '为啥', '为何', '如何才会', '怎么才会']
        self.err_effect_qwds = ['会导致', '会造成', '影响']
        self.solve_way_qwds = ['恢复', '正常', '解决', '还原', '变好']
        self.server_qwds = ['运行', '关链服务器', '服务器', '相关服务器']
        self.check_way_qwds = ['检查', '检查项目', '查出', '检查', '测出', '试出', '排查']
        self.link_module_qwds = ['属于什么模块', '属于', '什么功能模块', '模块', '有哪些模块']
        return

    '''分类主函数'''

    def classify(self, question):
        data = {}
        medical_dict = self.check_way_medical(question)
        if not medical_dict:
            return {}
        data['args'] = medical_dict
        # 收集问句当中所涉及到的实体类型
        types = []
        for type_ in medical_dict.values():
            types += type_
        question_type = 'others'

        question_types = []

        # 产生原因
        if self.check_way_words(self.err_cause_qwds, question) and ('error' in types):
            question_type = 'error_err_cause'
            question_types.append(question_type)

        if self.check_way_words(self.err_cause_qwds, question) and ('err_cause' in types):
            question_type = 'err_cause_error'
            question_types.append(question_type)

        # 解决方案
        if self.check_way_words(self.solve_way_qwds, question) and 'error' in types:
            question_type = 'error_solve_way'
            question_types.append(question_type)

        # 解决方法针对什么故障
        if self.check_way_words(self.solve_way_qwds, question) and 'solve_way' in types:
            question_type = 'solve_way_error'
            question_types.append(question_type)

        # 故障检查项目
        if self.check_way_words(self.check_way_qwds, question) and 'error' in types:
            question_type = 'error_check_way'
            question_types.append(question_type)

        # 已知检查项目查故障
        if self.check_way_words(self.check_way_qwds, question) and 'check_way' in types:
            question_type = 'check_way_error'
            question_types.append(question_type)

        # 故障相应服务器
        if self.check_way_words(self.server_qwds, question) and 'error' in types:
            question_type = 'error_server'
            question_types.append(question_type)
        if self.check_way_words(self.server_qwds, question) and 'server' in types:
            question_type = 'server_error'
            question_types.append(question_type)
        # 故障相应影响
        if self.check_way_words(self.err_effect_qwds, question) and 'error' in types:
            question_type = 'error_err_effect'
            question_types.append(question_type)
        if self.check_way_words(self.err_effect_qwds, question) and 'err_effect' in types:
            question_type = 'err_effect_error'
            question_types.append(question_type)
        # 相关模块
        if self.check_way_words(self.link_module_qwds, question) and 'error' in types:
            question_type = 'error_link_module'
            question_types.append(question_type)
        if self.check_way_words(self.link_module_qwds, question) and 'link_module' in types:
            question_type = 'link_module_error'
            question_types.append(question_type)

        # 若没有查到相关的外部查询信息，那么则将该疾病的描述信息返回
        if question_types == [] and 'error' in types:
            question_types = ['error_desc']
        if question_types == []:
            question_types = ['null']

        # 将多个分类结果进行合并处理，组装成一个字典
        data['question_types'] = question_types

        return data

    '''构造词对应的类型'''

    def build_wdtype_dict(self):
        wd_dict = dict()
        for wd in self.region_words:
            wd_dict[wd] = []
            if wd in self.error_wds:
                wd_dict[wd].append('error')
            if wd in self.link_module_wds:
                wd_dict[wd].append('link_module')
            if wd in self.check_way_wds:
                wd_dict[wd].append('check_way')
            if wd in self.solve_way_wds:
                wd_dict[wd].append('solve_way')
            if wd in self.server_wds:
                wd_dict[wd].append('server')
            if wd in self.err_cause_wds:
                wd_dict[wd].append('err_cause')
            if wd in self.err_effect_wds:
                wd_dict[wd].append('err_effect')
        return wd_dict

    '''构造actree，加速过滤'''

    def build_actree(self, wordlist):
        actree = ahocorasick.Automaton()
        for index, word in enumerate(wordlist):
            actree.add_word(word, (index, word))
        actree.make_automaton()
        return actree

    '''问句过滤'''

    def check_way_medical(self, question):
        region_wds = []
        for i in self.region_tree.iter(question):
            wd = i[1][1]
            region_wds.append(wd)
        stop_wds = []
        for wd1 in region_wds:
            for wd2 in region_wds:
                if wd1 in wd2 and wd1 != wd2:
                    stop_wds.append(wd1)
        final_wds = [i for i in region_wds if i not in stop_wds]
        final_dict = {i: self.wdtype_dict.get(i) for i in final_wds}

        return final_dict

    '''基于特征词进行分类'''

    def check_way_words(self, wds, sent):
        for wd in wds:
            if wd in sent:
                return True
        return False
